package peace.gui.controls.list
{
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.Shape;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;

import peace.gui.controls.Control;
import peace.gui.controls.SelectEvent;
import peace.gui.controls.buttons.PushButton;
import peace.gui.controls.scroll.Scrollbar;
import peace.gui.controls.text.InputField;
import peace.util.Display;

/**
 * Составной компонент из листбокса, инпута и кнопки 
 * @example
	<listing>
			var l:ListBox = new ListBox(["первый","второй","третий","четвертый","пятый","шестой"]);
			var c:ComboBox = new ComboBox(l);
			c.x = c.y = 50;
			c.addEventListener(SelectEvent.CHANGE, function(e:SelectEvent):void
			{
				Logger.msg(e.selection);
			});
			addChild(c);
	
	</listing>
 * 
 * 
 */
public class ComboBox extends Control
{
	/**
	 * 
	 */
	protected static const DEFAULT_WIDTH:Number = 100;
	/**
	 * 
	 */
	protected static const MAX_LIST_HEIGHT:Number = 100;
	/**
	 * открываем лист чтобы не делегировать интерфейс  
	 */	
	public var list:ListBox;
	/**
	 * 
	 */	
	protected var button:PushButton;
	/**
	 * Input для ввода или контрол если просто кнопка 
	 */	
	protected var input:Control;
	/**
	 * 
	 */	
	protected var allowInput:Boolean;
	
	/**
	 * 
	 * @param list лист-бокс со значениями
	 * @param input
	 * @param button
	 * @param allowInput можно ли вбивать значения в инпут
	 * 
	 */	
	public function ComboBox (	list:ListBox,
								input:Control = null,
								button:PushButton = null,
								allowInput:Boolean = false) 
	{
		super();
		
		this.allowInput = allowInput;
		
		init(list, input, button);
	}
	
	private function init(	list:ListBox,
							input:Control = null,
							button:PushButton = null):void
	{
		
		input = input || getInput();
		this.input = input;
		input.addEventListener(MouseEvent.CLICK, onToggle, false,0,true);
		if (input is TextField && !allowInput)
		{
			input.mouseChildren = false;
		}
		addChild(input);
		
		button = button || getArrowButton();
		this.button = button;
		button.addEventListener(MouseEvent.CLICK, onToggle, false,0,true);
		addChild(button);
		
		this.list = list;
		list.allowRadioMode = true;
		list.addEventListener(SelectEvent.CHANGE, onChangeSelection, false,0,true);
		list.addEventListener(MouseEvent.CLICK, onListClick, false,0,true);
		if (list.height > MAX_LIST_HEIGHT) list.height = MAX_LIST_HEIGHT;
		listVisible = false;
		
		dropShade();
		
		width = DEFAULT_WIDTH;
		
		addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage, false,0,true);
	}
	/**
	 * 
	 * @param e
	 * 
	 */	
	private function onToggle (e:Event):void
	{
		listVisible = ! list.visible;
	}
	/**
	 * 
	 * @param e
	 * 
	 */	
	private function onChangeSelection (e:SelectEvent):void
	{
		var obj:Object = e.selection;
		input.value = obj ? obj.toString() : "";
		dispatchEvent(new SelectEvent(SelectEvent.CHANGE, obj));
	}
	/**
	 * 
	 * @param e
	 * 
	 */	
	private function onListClick (e:MouseEvent):void
	{
		// по скроллбару можно кликать
		if (DisplayObject(e.target).parent is Scrollbar) return;
		
		listVisible = false;
	}
	/**
	 * 
	 * @param e
	 * 
	 */	
	private function onStageMouseDown (e:Event):void
	{
		var d:DisplayObject = DisplayObject (e.target);
		if (! Display.isChild(d, this) && ! Display.isChild(d, list))
		{
			listVisible = false;
		}
	}
	
	/**
	 * 
	 * @param b
	 * 
	 */	
	protected function set listVisible (b:Boolean):void
	{
		if (stage)
		{
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown, false,0,true);
		}
		
		if (stage && b)
		{
			stage.addChild(list);
			
			// располагаем лист
			var p:Point = new Point (0, input.height);
			p = localToGlobal(p);
			list.x = p.x;
			list.y = p.y + 1;
		}

		list.visible = b;
	}
	
	protected function onRemovedFromStage (e:Event):void
	{
		if (stage.contains(list))
		{
			stage.removeChild(list);
		}
		stage.removeEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
	}
	/**
	 * 
	 * @param v объект или массив объектов
	 * 
	 */	
	override public function set value(v:*):void
	{
		list.value = v;
	}
	/**
	 * 
	 * @return 
	 * 
	 */	
	override public function get value ():*
	{
		return list.value;
	}
	/**
	 * Выделяем по индексу элемента
	 *  
	 * @param index
	 * 
	 */	
	public function set selectedIndex (index:int):void
	{
		list.selectedIndex = index;
	}
	/**
	 * 
	 * @return 
	 * 
	 */	
	public function get selectedIndex ():int
	{
		return list.selectedIndex;
	}
	
	
	/**
	 * 
	 * @param value
	 * 
	 */	
	override public function set width(value:Number):void
	{
		input.width = value - button.width;
		button.x = input.width;
		
		list.width = value;
	}
	/**
	 * @private
	 * 
	 * Рисуем дефолтный скин для кнопки
	 *  
	 * @return 
	 * 
	 */	
	private function getArrowButton ():PushButton
	{
		var out:Shape = new Shape();
		var g:Graphics = out.graphics;
		g.lineStyle(0);
		g.beginFill(0xcccccc);
		g.drawRect(0,0,20,20);
		
		var l:TextField = new TextField();
		l.mouseEnabled = l.selectable = false;
		l.autoSize = TextFieldAutoSize.LEFT;
		l.defaultTextFormat = new TextFormat("Arial", 12, 0, true)
		l.text = "V";
		
		return new PushButton(out,null,null,null,null,l);
	}
	/**
	 * @private
	 * 
	 * @return 
	 * 
	 */	
	private function getInput ():InputField
	{
		var i:InputField = new InputField();
		i.height = 20;
		return i;
	}
	
	private function dropShade ():void
	{
		var s:DropShadowFilter = new DropShadowFilter(0,0,0, 0.3, 4, 4, 1, 3)
		list.filters = [s];
	}
}
}